import java.util.LinkedList;


public class Station {
	private LinkedList<Measurement> history = new LinkedList<Measurement>();	//keeps last 30 measurements
	
	public boolean isHistoryFilled() {
		if(history.size() == 30) return true;
		return false;
	}
	
	public void addMeasurement(Measurement measurement) {
		if(history.size() == 30) history.removeFirst();
		history.addLast(measurement);

	}
	
	public int getSize() {
		return history.size();
	}
	
	public float differenceQuotient(long x1, long x2, float y1, float y2) {
		//You cannot divide by zero, so if it happens a 0 will be returned.
		if(y2 - y1 == 0 || x2 - x1 == 0) return 0;
		return (y2 - y1) / (x2 - x1);
	}
	
	// Check 20% off tempratures
	public void checkTemp(Measurement measurement) {
		float prediction = predictTemp();
		float temp = measurement.getTemp();
		if((temp - prediction) / temp > 0.2) {
			System.out.println("Correction: temp 20% off prediction; old: " + temp + "; new: " + prediction);
			measurement.setTemp(prediction);
		}
	}

	public float predictTemp() {
		Measurement first = history.getFirst();
		Measurement last = history.getLast();
		long x1 = first.getDateTime();
		long x2 = last.getDateTime();
		float y1 = first.getTemp();
		float y2 = last.getTemp();
		return y2 + differenceQuotient(x1,x2,y1,y2);
	}
	
	public void predict(String field, Measurement measurement) {
		Measurement first = history.getFirst();
		Measurement last = history.getLast();
		long x1 = first.getDateTime();
		long x2 = last.getDateTime();	
		float y1 = 0;
		float y2 = 0;
		
		switch(field) {
			case "temp":
				measurement.setTemp(predictTemp());
				break;
			case "dewp":
				y1 = first.getDewp();
				y2 = last.getDewp();
				measurement.setDewp(y2 + differenceQuotient(x1,x2,y1,y2));
				break;
			case "stp":
				y1 = first.getStp();
				y2 = last.getStp();
				measurement.setStp(y2 + differenceQuotient(x1,x2,y1,y2));
				break;
			case "slp":
				y1 = first.getSlp();
				y2 = last.getSlp();
				measurement.setSlp(y2 + differenceQuotient(x1,x2,y1,y2));
				break;
			case "visib":
				y1 = first.getVisib();
				y2 = last.getVisib();
				measurement.setVisib(y2 + differenceQuotient(x1,x2,y1,y2));
				break;
			case "wdsp":
				y1 = first.getWdsp();
				y2 = last.getWdsp();
				measurement.setWdsp(y2 + differenceQuotient(x1,x2,y1,y2));
				break;
			case "prcp":
				y1 = first.getPrcp();
				y2 = last.getPrcp();
				measurement.setPrcp(y2 + differenceQuotient(x1,x2,y1,y2));
				break;
			case "sndp":
				y1 = first.getSndp();
				y2 = last.getSndp();
				measurement.setSndp(y2 + differenceQuotient(x1,x2,y1,y2));
				break;
			case "frshtt":
				// For FSHTT a prediction can not be made by calculating the previous increment averages.
				// So if FRSHTT is missing, we take the value from the previous day.
				measurement.setFrshtt(last.getFrshtt());
				break;
			case "cldc":
				y1 = first.getCldc();
				y2 = last.getCldc();
				measurement.setCldc(y2 + differenceQuotient(x1,x2,y1,y2));
				break;
			case "wnddir":
				y1 = first.getWnddir();
				y2 = last.getWnddir();
				// Wnddir is an Integer, cast to int
				int result = (int) (y2 + differenceQuotient(x1,x2,y1,y2));
				measurement.setWnddir(result);
				break;
		}
		System.out.println(field + " corrected");
	
	}

}
